home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / intoids.lha / Intoids 1.0 / GNU Originals / Integer.cc next >
C/C++ Source or Header  |  1995-06-16  |  47KB  |  2,283 lines

  1. /* 
  2. Copyright (C) 1988 Free Software Foundation
  3.     written by Doug Lea (dl@rocky.oswego.edu)
  4.  
  5. This file is part of the GNU C++ Library.  This library is free
  6. software; you can redistribute it and/or modify it under the terms of
  7. the GNU Library General Public License as published by the Free
  8. Software Foundation; either version 2 of the License, or (at your
  9. option) any later version.  This library is distributed in the hope
  10. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  11. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12. PURPOSE.  See the GNU Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  16. */
  17.  
  18. /*
  19.   Some of the following algorithms are very loosely based on those from 
  20.   MIT C-Scheme bignum.c, which is
  21.       Copyright (c) 1987 Massachusetts Institute of Technology
  22.  
  23.   with other guidance from Knuth, vol. 2
  24.  
  25.   Thanks to the creators of the algorithms.
  26. */
  27.  
  28. #ifdef __GNUG__
  29. #pragma implementation
  30. #endif
  31. #include <Integer.h>
  32. #include <std.h>
  33. #include <ctype.h>
  34. #include <limits.h>
  35. #include <Obstack.h>
  36. #include <AllocRing.h>
  37. #include <new.h>
  38. #include <builtin.h>
  39. #include "Integer.hP"
  40.  
  41. #undef OK
  42.  
  43. IntRep _ZeroRep = {1, 0, 1, {0}};
  44. IntRep _OneRep = {1, 0, 1, {1}};
  45. IntRep _MinusOneRep = {1, 0, 0, {1}};
  46.  
  47.  
  48. // utilities to extract and transfer bits 
  49.  
  50. // get low bits
  51.  
  52. inline static unsigned short extract(unsigned long x)
  53. {
  54.   return x & I_MAXNUM;
  55. }
  56.  
  57. // transfer high bits to low
  58.  
  59. inline static unsigned long down(unsigned long x)
  60. {
  61.   return (x >> I_SHIFT) & I_MAXNUM;
  62. }
  63.  
  64. // transfer low bits to high
  65.  
  66. inline static unsigned long up(unsigned long x)
  67. {
  68.   return x << I_SHIFT;
  69. }
  70.  
  71. // compare two equal-length reps
  72.  
  73. inline static int docmp(const unsigned short* x, const unsigned short* y, int l)
  74. {
  75.   int diff = 0;
  76.   const unsigned short* xs = &(x[l]);
  77.   const unsigned short* ys = &(y[l]);
  78.   while (l-- > 0 && (diff = (*--xs) - (*--ys)) == 0);
  79.   return diff;
  80. }
  81.  
  82. // figure out max length of result of +, -, etc.
  83.  
  84. inline static int calc_len(int len1, int len2, int pad)
  85. {
  86.   return (len1 >= len2)? len1 + pad : len2 + pad;
  87. }
  88.  
  89. // ensure len & sgn are correct
  90.  
  91. inline static void Icheck(IntRep* rep)
  92. {
  93.   int l = rep->len;
  94.   const unsigned short* p = &(rep->s[l]);
  95.   while (l > 0 && *--p == 0) --l;
  96.   if ((rep->len = l) == 0) rep->sgn = I_POSITIVE;
  97. }
  98.  
  99.  
  100. // zero out the end of a rep
  101.  
  102. inline static void Iclear_from(IntRep* rep, int p)
  103. {
  104.   unsigned short* cp = &(rep->s[p]);
  105.   const unsigned short* cf = &(rep->s[rep->len]);
  106.   while(cp < cf) *cp++ = 0;
  107. }
  108.  
  109. // copy parts of a rep
  110.  
  111. static inline void scpy(const unsigned short* src, unsigned short* dest,int nb)
  112. {
  113.   while (--nb >= 0) *dest++ = *src++;
  114. }
  115.  
  116. // make sure an argument is valid
  117.  
  118. static inline void nonnil(const IntRep* rep)
  119. {
  120.   if (rep == 0) 
  121.     (*lib_error_handler)("Integer", "operation on uninitialized Integer");
  122. }
  123.  
  124. // allocate a new Irep. Pad to something close to a power of two.
  125.  
  126. inline static IntRep* Inew(int newlen)
  127. {
  128.   unsigned int siz = sizeof(IntRep) + newlen * sizeof(short) + 
  129.     MALLOC_MIN_OVERHEAD;
  130.   unsigned int allocsiz = MINIntRep_SIZE;
  131.   while (allocsiz < siz) allocsiz <<= 1;  // find a power of 2
  132.   allocsiz -= MALLOC_MIN_OVERHEAD;
  133.   if (allocsiz >= MAXIntRep_SIZE * sizeof(short))
  134.     (*lib_error_handler)("Integer", "Requested length out of range");
  135.     
  136.   IntRep* rep = new (operator new (allocsiz)) IntRep;
  137.   rep->sz = (allocsiz - sizeof(IntRep) + sizeof(short)) / sizeof(short);
  138.   return rep;
  139. }
  140.  
  141. // allocate: use the bits in src if non-null, clear the rest
  142.  
  143. IntRep* Ialloc(IntRep* old, const unsigned short* src, int srclen, int newsgn,
  144.               int newlen)
  145. {
  146.   IntRep* rep;
  147.   if (old == 0 || newlen > old->sz)
  148.     rep = Inew(newlen);
  149.   else
  150.     rep = old;
  151.  
  152.   rep->len = newlen;
  153.   rep->sgn = newsgn;
  154.  
  155.   scpy(src, rep->s, srclen);
  156.   Iclear_from(rep, srclen);
  157.  
  158.   if (old != rep && old != 0 && !STATIC_IntRep(old)) delete old;
  159.   return rep;
  160. }
  161.  
  162. // allocate and clear
  163.  
  164. IntRep* Icalloc(IntRep* old, int newlen)
  165. {
  166.   IntRep* rep;
  167.   if (old == 0 || newlen > old->sz)
  168.   {
  169.     if (old != 0 && !STATIC_IntRep(old)) delete old;
  170.     rep = Inew(newlen);
  171.   }
  172.   else
  173.     rep = old;
  174.  
  175.   rep->len = newlen;
  176.   rep->sgn = I_POSITIVE;
  177.   Iclear_from(rep, 0);
  178.  
  179.   return rep;
  180. }
  181.  
  182. // reallocate
  183.  
  184. IntRep* Iresize(IntRep* old, int newlen)
  185. {
  186.   IntRep* rep;
  187.   unsigned short oldlen;
  188.   if (old == 0)
  189.   {
  190.     oldlen = 0;
  191.     rep = Inew(newlen);
  192.     rep->sgn = I_POSITIVE;
  193.   }
  194.   else 
  195.   {
  196.     oldlen = old->len;
  197.     if (newlen > old->sz)
  198.     {
  199.       rep = Inew(newlen);
  200.       scpy(old->s, rep->s, oldlen);
  201.       rep->sgn = old->sgn;
  202.       if (!STATIC_IntRep(old)) delete old;
  203.     }
  204.     else
  205.       rep = old;
  206.   }
  207.  
  208.   rep->len = newlen;
  209.   Iclear_from(rep, oldlen);
  210.  
  211.   return rep;
  212. }
  213.  
  214.  
  215. // same, for straight copy
  216.  
  217. IntRep* Icopy(IntRep* old, const IntRep* src)
  218. {
  219.   if (old == src) return old; 
  220.   IntRep* rep;
  221.   if (src == 0)
  222.   {
  223.     if (old == 0)
  224.       rep = Inew(0);
  225.     else
  226.     {
  227.       rep = old;
  228.       Iclear_from(rep, 0);
  229.     }
  230.     rep->len = 0;
  231.     rep->sgn = I_POSITIVE;
  232.   }
  233.   else 
  234.   {
  235.     int newlen = src->len;
  236.     if (old == 0 || newlen > old->sz)
  237.     {
  238.       if (old != 0 && !STATIC_IntRep(old)) delete old;
  239.       rep = Inew(newlen);
  240.     }
  241.     else
  242.       rep = old;
  243.  
  244.     rep->len = newlen;
  245.     rep->sgn = src->sgn;
  246.  
  247.     scpy(src->s, rep->s, newlen);
  248.   }
  249.  
  250.   return rep;
  251. }
  252.  
  253. // allocate & copy space for a long
  254.  
  255. IntRep* Icopy_long(IntRep* old, long x)
  256. {
  257.   int newsgn = (x >= 0);
  258.   IntRep* rep = Icopy_ulong(old, newsgn ? x : -x);
  259.   rep->sgn = newsgn;
  260.   return rep;
  261. }
  262.  
  263. IntRep* Icopy_ulong(IntRep* old, unsigned long x)
  264. {
  265.   unsigned short src[SHORT_PER_LONG];
  266.   
  267.   unsigned short srclen = 0;
  268.   while (x != 0)
  269.   {
  270.     src[srclen++] = extract(x);
  271.     x = down(x);
  272.   }
  273.  
  274.   IntRep* rep;
  275.   if (old == 0 || srclen > old->sz)
  276.   {
  277.     if (old != 0 && !STATIC_IntRep(old)) delete old;
  278.     rep = Inew(srclen);
  279.   }
  280.   else
  281.     rep = old;
  282.  
  283.   rep->len = srclen;
  284.   rep->sgn = I_POSITIVE;
  285.  
  286.   scpy(src, rep->s, srclen);
  287.  
  288.   return rep;
  289. }
  290.  
  291. // special case for zero -- it's worth it!
  292.  
  293. IntRep* Icopy_zero(IntRep* old)
  294. {
  295.   if (old == 0 || STATIC_IntRep(old))
  296.     return &_ZeroRep;
  297.  
  298.   old->len = 0;
  299.   old->sgn = I_POSITIVE;
  300.  
  301.   return old;
  302. }
  303.  
  304. // special case for 1 or -1
  305.  
  306. IntRep* Icopy_one(IntRep* old, int newsgn)
  307. {
  308.   if (old == 0 || 1 > old->sz)
  309.   {
  310.     if (old != 0 && !STATIC_IntRep(old)) delete old;
  311.     return newsgn==I_NEGATIVE ? &_MinusOneRep : &_OneRep;
  312.   }
  313.  
  314.   old->sgn = newsgn;
  315.   old->len = 1;
  316.   old->s[0] = 1;
  317.  
  318.   return old;
  319. }
  320.  
  321. // convert to a legal two's complement long if possible
  322. // if too big, return most negative/positive value
  323.  
  324. long Itolong(const IntRep* rep)
  325.   if ((unsigned)(rep->len) > (unsigned)(SHORT_PER_LONG))
  326.     return (rep->sgn == I_POSITIVE) ? LONG_MAX : LONG_MIN;
  327.   else if (rep->len == 0)
  328.     return 0;
  329.   else if ((unsigned)(rep->len) < (unsigned)(SHORT_PER_LONG))
  330.   {
  331.     unsigned long a = rep->s[rep->len-1];
  332.     if (SHORT_PER_LONG > 2) // normally optimized out
  333.     {
  334.       for (int i = rep->len - 2; i >= 0; --i)
  335.         a = up(a) | rep->s[i];
  336.     }
  337.     return (rep->sgn == I_POSITIVE)? a : -((long)a);
  338.   }
  339.   else 
  340.   {
  341.     unsigned long a = rep->s[SHORT_PER_LONG - 1];
  342.     if (a >= I_MINNUM)
  343.       return (rep->sgn == I_POSITIVE) ? LONG_MAX : LONG_MIN;
  344.     else
  345.     {
  346.       a = up(a) | rep->s[SHORT_PER_LONG - 2];
  347.       if (SHORT_PER_LONG > 2)
  348.       {
  349.         for (int i = SHORT_PER_LONG - 3; i >= 0; --i)
  350.           a = up(a) | rep->s[i];
  351.       }
  352.       return (rep->sgn == I_POSITIVE)? a : -((long)a);
  353.     }
  354.   }
  355. }
  356.  
  357. // test whether op long() will work.
  358. // careful about asymmetry between LONG_MIN & LONG_MAX
  359.  
  360. int Iislong(const IntRep* rep)
  361. {
  362.   unsigned int l = rep->len;
  363.   if (l < SHORT_PER_LONG)
  364.     return 1;
  365.   else if (l > SHORT_PER_LONG)
  366.     return 0;
  367.   else if ((unsigned)(rep->s[SHORT_PER_LONG - 1]) < (unsigned)(I_MINNUM))
  368.     return 1;
  369.   else if (rep->sgn == I_NEGATIVE && rep->s[SHORT_PER_LONG - 1] == I_MINNUM)
  370.   {
  371.     for (unsigned int i = 0; i < SHORT_PER_LONG - 1; ++i)
  372.       if (rep->s[i] != 0)
  373.         return 0;
  374.     return 1;
  375.   }
  376.   else
  377.     return 0;
  378. }
  379.  
  380. // comparison functions
  381.   
  382. int compare(const IntRep* x, const IntRep* y)
  383. {
  384.   int diff  = x->sgn - y->sgn;
  385.   if (diff == 0)
  386.   {
  387.     diff = x->len - y->len;
  388.     if (diff == 0)
  389.       diff = docmp(x->s, y->s, x->len);
  390.     if (x->sgn == I_NEGATIVE)
  391.       diff = -diff;
  392.   }
  393.   return diff;
  394. }
  395.  
  396. int ucompare(const IntRep* x, const IntRep* y)
  397. {
  398.   int diff = x->len - y->len;
  399.   if (diff == 0)
  400.   {
  401.     int l = x->len;
  402.     const unsigned short* xs = &(x->s[l]);
  403.     const unsigned short* ys = &(y->s[l]);
  404.     while (l-- > 0 && (diff = (*--xs) - (*--ys)) == 0);
  405.   }
  406.   return diff;
  407. }
  408.  
  409. int compare(const IntRep* x, long  y)
  410. {
  411.   int xl = x->len;
  412.   int xsgn = x->sgn;
  413.   if (y == 0)
  414.   {
  415.     if (xl == 0)
  416.       return 0;
  417.     else if (xsgn == I_NEGATIVE)
  418.       return -1;
  419.     else
  420.       return 1;
  421.   }
  422.   else
  423.   {
  424.     int ysgn = y >= 0;
  425.     unsigned long uy = (ysgn)? y : -y;
  426.     int diff = xsgn - ysgn;
  427.     if (diff == 0)
  428.     {
  429.       diff = xl - SHORT_PER_LONG;
  430.       if (diff <= 0)
  431.       {
  432.         unsigned short tmp[SHORT_PER_LONG];
  433.         int yl = 0;
  434.         while (uy != 0)
  435.         {
  436.           tmp[yl++] = extract(uy);
  437.           uy = down(uy);
  438.         }
  439.         diff = xl - yl;
  440.         if (diff == 0)
  441.           diff = docmp(x->s, tmp, xl);
  442.       }
  443.       if (xsgn == I_NEGATIVE)
  444.     diff = -diff;
  445.     }
  446.     return diff;
  447.   }
  448. }
  449.  
  450. int ucompare(const IntRep* x, long  y)
  451. {
  452.   int xl = x->len;
  453.   if (y == 0)
  454.     return xl;
  455.   else
  456.   {
  457.     unsigned long uy = (y >= 0)? y : -y;
  458.     int diff = xl - SHORT_PER_LONG;
  459.     if (diff <= 0)
  460.     {
  461.       unsigned short tmp[SHORT_PER_LONG];
  462.       int yl = 0;
  463.       while (uy != 0)
  464.       {
  465.         tmp[yl++] = extract(uy);
  466.         uy = down(uy);
  467.       }
  468.       diff = xl - yl;
  469.       if (diff == 0)
  470.         diff = docmp(x->s, tmp, xl);
  471.     }
  472.     return diff;
  473.   }
  474. }
  475.  
  476.  
  477.  
  478. // arithmetic functions
  479.  
  480. IntRep* add(const IntRep* x, int negatex, 
  481.             const IntRep* y, int negatey, IntRep* r)
  482. {
  483.   nonnil(x);
  484.   nonnil(y);
  485.  
  486.   int xl = x->len;
  487.   int yl = y->len;
  488.  
  489.   int xsgn = (negatex && xl != 0) ? !x->sgn : x->sgn;
  490.   int ysgn = (negatey && yl != 0) ? !y->sgn : y->sgn;
  491.  
  492.   int xrsame = x == r;
  493.   int yrsame = y == r;
  494.  
  495.   if (yl == 0)
  496.     r = Ialloc(r, x->s, xl, xsgn, xl);
  497.   else if (xl == 0)
  498.     r = Ialloc(r, y->s, yl, ysgn, yl);
  499.   else if (xsgn == ysgn)
  500.   {
  501.     if (xrsame || yrsame)
  502.       r = Iresize(r, calc_len(xl, yl, 1));
  503.     else
  504.       r = Icalloc(r, calc_len(xl, yl, 1));
  505.     r->sgn = xsgn;
  506.     unsigned short* rs = r->s;
  507.     const unsigned short* as;
  508.     const unsigned short* bs;
  509.     const unsigned short* topa;
  510.     const unsigned short* topb;
  511.     if (xl >= yl)
  512.     {
  513.       as =  (xrsame)? r->s : x->s;
  514.       topa = &(as[xl]);
  515.       bs =  (yrsame)? r->s : y->s;
  516.       topb = &(bs[yl]);
  517.     }
  518.     else
  519.     {
  520.       bs =  (xrsame)? r->s : x->s;
  521.       topb = &(bs[xl]);
  522.       as =  (yrsame)? r->s : y->s;
  523.       topa = &(as[yl]);
  524.     }
  525.     unsigned long sum = 0;
  526.     while (bs < topb)
  527.     {
  528.       sum += (unsigned long)(*as++) + (unsigned long)(*bs++);
  529.       *rs++ = extract(sum);
  530.       sum = down(sum);
  531.     }
  532.     while (sum != 0 && as < topa)
  533.     {
  534.       sum += (unsigned long)(*as++);
  535.       *rs++ = extract(sum);
  536.       sum = down(sum);
  537.     }
  538.     if (sum != 0)
  539.       *rs = extract(sum);
  540.     else if (rs != as)
  541.       while (as < topa)
  542.         *rs++ = *as++;
  543.   }
  544.   else
  545.   {
  546.     int comp = ucompare(x, y);
  547.     if (comp == 0)
  548.       r = Icopy_zero(r);
  549.     else
  550.     {
  551.       if (xrsame || yrsame)
  552.         r = Iresize(r, calc_len(xl, yl, 0));
  553.       else
  554.         r = Icalloc(r, calc_len(xl, yl, 0));
  555.       unsigned short* rs = r->s;
  556.       const unsigned short* as;
  557.       const unsigned short* bs;
  558.       const unsigned short* topa;
  559.       const unsigned short* topb;
  560.       if (comp > 0)
  561.       {
  562.         as =  (xrsame)? r->s : x->s;
  563.         topa = &(as[xl]);
  564.         bs =  (yrsame)? r->s : y->s;
  565.         topb = &(bs[yl]);
  566.         r->sgn = xsgn;
  567.       }
  568.       else
  569.       {
  570.         bs =  (xrsame)? r->s : x->s;
  571.         topb = &(bs[xl]);
  572.         as =  (yrsame)? r->s : y->s;
  573.         topa = &(as[yl]);
  574.         r->sgn = ysgn;
  575.       }
  576.       unsigned long hi = 1;
  577.       while (bs < topb)
  578.       {
  579.         hi += (unsigned long)(*as++) + I_MAXNUM - (unsigned long)(*bs++);
  580.         *rs++ = extract(hi);
  581.         hi = down(hi);
  582.       }
  583.       while (hi == 0 && as < topa)
  584.       {
  585.         hi = (unsigned long)(*as++) + I_MAXNUM;
  586.         *rs++ = extract(hi);
  587.         hi = down(hi);
  588.       }
  589.       if (rs != as)
  590.         while (as < topa)
  591.           *rs++ = *as++;
  592.     }
  593.   }
  594.   Icheck(r);
  595.   return r;
  596. }
  597.  
  598.  
  599. IntRep* add(const IntRep* x, int negatex, long y, IntRep* r)
  600. {
  601.   nonnil(x);
  602.   int xl = x->len;
  603.   int xsgn = (negatex && xl != 0) ? !x->sgn : x->sgn;
  604.   int xrsame = x == r;
  605.  
  606.   int ysgn = (y >= 0);
  607.   unsigned long uy = (ysgn)? y : -y;
  608.  
  609.   if (y == 0)
  610.     r = Ialloc(r, x->s, xl, xsgn, xl);
  611.   else if (xl == 0)
  612.     r = Icopy_long(r, y);
  613.   else if (xsgn == ysgn)
  614.   {
  615.     if (xrsame)
  616.       r = Iresize(r, calc_len(xl, SHORT_PER_LONG, 1));
  617.     else
  618.       r = Icalloc(r, calc_len(xl, SHORT_PER_LONG, 1));
  619.     r->sgn = xsgn;
  620.     unsigned short* rs = r->s;
  621.     const unsigned short* as =  (xrsame)? r->s : x->s;
  622.     const unsigned short* topa = &(as[xl]);
  623.     unsigned long sum = 0;
  624.     while (as < topa && uy != 0)
  625.     {
  626.       unsigned long u = extract(uy);
  627.       uy = down(uy);
  628.       sum += (unsigned long)(*as++) + u;
  629.       *rs++ = extract(sum);
  630.       sum = down(sum);
  631.     }
  632.     while (sum != 0 && as < topa)
  633.     {
  634.       sum += (unsigned long)(*as++);
  635.       *rs++ = extract(sum);
  636.       sum = down(sum);
  637.     }
  638.     if (sum != 0)
  639.       *rs = extract(sum);
  640.     else if (rs != as)
  641.       while (as < topa)
  642.         *rs++ = *as++;
  643.   }
  644.   else
  645.   {
  646.     unsigned short tmp[SHORT_PER_LONG];
  647.     int yl = 0;
  648.     while (uy != 0)
  649.     {
  650.       tmp[yl++] = extract(uy);
  651.       uy = down(uy);
  652.     }
  653.     int comp = xl - yl;
  654.     if (comp == 0)
  655.       comp = docmp(x->s, tmp, yl);
  656.     if (comp == 0)
  657.       r = Icopy_zero(r);
  658.     else
  659.     {
  660.       if (xrsame)
  661.         r = Iresize(r, calc_len(xl, yl, 0));
  662.       else
  663.         r = Icalloc(r, calc_len(xl, yl, 0));
  664.       unsigned short* rs = r->s;
  665.       const unsigned short* as;
  666.       const unsigned short* bs;
  667.       const unsigned short* topa;
  668.       const unsigned short* topb;
  669.       if (comp > 0)
  670.       {
  671.         as =  (xrsame)? r->s : x->s;
  672.         topa = &(as[xl]);
  673.         bs =  tmp;
  674.         topb = &(bs[yl]);
  675.         r->sgn = xsgn;
  676.       }
  677.       else
  678.       {
  679.         bs =  (xrsame)? r->s : x->s;
  680.         topb = &(bs[xl]);
  681.         as =  tmp;
  682.         topa = &(as[yl]);
  683.         r->sgn = ysgn;
  684.       }
  685.       unsigned long hi = 1;
  686.       while (bs < topb)
  687.       {
  688.         hi += (unsigned long)(*as++) + I_MAXNUM - (unsigned long)(*bs++);
  689.         *rs++ = extract(hi);
  690.         hi = down(hi);
  691.       }
  692.       while (hi == 0 && as < topa)
  693.       {
  694.         hi = (unsigned long)(*as++) + I_MAXNUM;
  695.         *rs++ = extract(hi);
  696.         hi = down(hi);
  697.       }
  698.       if (rs != as)
  699.         while (as < topa)
  700.           *rs++ = *as++;
  701.     }
  702.   }
  703.   Icheck(r);
  704.   return r;
  705. }
  706.  
  707.  
  708. IntRep* multiply(const IntRep* x, const IntRep* y, IntRep* r)
  709. {
  710.   nonnil(x);
  711.   nonnil(y);
  712.   int xl = x->len;
  713.   int yl = y->len;
  714.   int rl = xl + yl;
  715.   int rsgn = x->sgn == y->sgn;
  716.   int xrsame = x == r;
  717.   int yrsame = y == r;
  718.   int xysame = x == y;
  719.   
  720.   if (xl == 0 || yl == 0)
  721.     r = Icopy_zero(r);
  722.   else if (xl == 1 && x->s[0] == 1)
  723.     r = Icopy(r, y);
  724.   else if (yl == 1 && y->s[0] == 1)
  725.     r = Icopy(r, x);
  726.   else if (!(xysame && xrsame))
  727.   {
  728.     if (xrsame || yrsame)
  729.       r = Iresize(r, rl);
  730.     else
  731.       r = Icalloc(r, rl);
  732.     unsigned short* rs = r->s;
  733.     unsigned short* topr = &(rs[rl]);
  734.  
  735.     // use best inner/outer loop params given constraints
  736.     unsigned short* currentr;
  737.     const unsigned short* bota;
  738.     const unsigned short* as;
  739.     const unsigned short* botb;
  740.     const unsigned short* topb;
  741.     if (xrsame)                 
  742.     { 
  743.       currentr = &(rs[xl-1]);
  744.       bota = rs;
  745.       as = currentr;
  746.       botb = y->s;
  747.       topb = &(botb[yl]);
  748.     }
  749.     else if (yrsame)
  750.     {
  751.       currentr = &(rs[yl-1]);
  752.       bota = rs;
  753.       as = currentr;
  754.       botb = x->s;
  755.       topb = &(botb[xl]);
  756.     }
  757.     else if (xl <= yl)
  758.     {
  759.       currentr = &(rs[xl-1]);
  760.       bota = x->s;
  761.       as = &(bota[xl-1]);
  762.       botb = y->s;
  763.       topb = &(botb[yl]);
  764.     }
  765.     else
  766.     {
  767.       currentr = &(rs[yl-1]);
  768.       bota = y->s;
  769.       as = &(bota[yl-1]);
  770.       botb = x->s;
  771.       topb = &(botb[xl]);
  772.     }
  773.  
  774.     while (as >= bota)
  775.     {
  776.       unsigned long ai = (unsigned long)(*as--);
  777.       unsigned short* rs = currentr--;
  778.       *rs = 0;
  779.       if (ai != 0)
  780.       {
  781.         unsigned long sum = 0;
  782.         const unsigned short* bs = botb;
  783.         while (bs < topb)
  784.         {
  785.           sum += ai * (unsigned long)(*bs++) + (unsigned long)(*rs);
  786.           *rs++ = extract(sum);
  787.           sum = down(sum);
  788.         }
  789.         while (sum != 0 && rs < topr)
  790.         {
  791.           sum += (unsigned long)(*rs);
  792.           *rs++ = extract(sum);
  793.           sum = down(sum);
  794.         }
  795.       }
  796.     }
  797.   }
  798.   else                          // x, y, and r same; compute over diagonals
  799.   {
  800.     r = Iresize(r, rl);
  801.     unsigned short* botr = r->s;
  802.     unsigned short* topr = &(botr[rl]);
  803.     unsigned short* rs =   &(botr[rl - 2]);
  804.  
  805.     const unsigned short* bota = (xrsame)? botr : x->s;
  806.     const unsigned short* loa =  &(bota[xl - 1]);
  807.     const unsigned short* hia =  loa;
  808.  
  809.     for (; rs >= botr; --rs)
  810.     {
  811.       const unsigned short* h = hia;
  812.       const unsigned short* l = loa;
  813.       unsigned long prod = (unsigned long)(*h) * (unsigned long)(*l);
  814.       *rs = 0;
  815.  
  816.       for(;;)
  817.       {
  818.         unsigned short* rt = rs;
  819.         unsigned long sum = prod + (unsigned long)(*rt);
  820.         *rt++ = extract(sum);
  821.         sum = down(sum);
  822.         while (sum != 0 && rt < topr)
  823.         {
  824.           sum += (unsigned long)(*rt);
  825.           *rt++ = extract(sum);
  826.           sum = down(sum);
  827.         }
  828.         if (h > l)
  829.         {
  830.           rt = rs;
  831.           sum = prod + (unsigned long)(*rt);
  832.           *rt++ = extract(sum);
  833.           sum = down(sum);
  834.           while (sum != 0 && rt < topr)
  835.           {
  836.             sum += (unsigned long)(*rt);
  837.             *rt++ = extract(sum);
  838.             sum = down(sum);
  839.           }
  840.           if (--h >= ++l)
  841.             prod = (unsigned long)(*h) * (unsigned long)(*l);
  842.           else
  843.             break;
  844.         }
  845.         else
  846.           break;
  847.       }
  848.       if (loa > bota)
  849.         --loa;
  850.       else
  851.         --hia;
  852.     }
  853.   }
  854.   r->sgn = rsgn;
  855.   Icheck(r);
  856.   return r;
  857. }
  858.  
  859.  
  860. IntRep* multiply(const IntRep* x, long y, IntRep* r)
  861. {
  862.   nonnil(x);
  863.   int xl = x->len;
  864.     
  865.   if (xl == 0 || y == 0)
  866.     r = Icopy_zero(r);
  867.   else if (y == 1)
  868.     r = Icopy(r, x);
  869.   else
  870.   {
  871.     int ysgn = y >= 0;
  872.     int rsgn = x->sgn == ysgn;
  873.     unsigned long uy = (ysgn)? y : -y;
  874.     unsigned short tmp[SHORT_PER_LONG];
  875.     int yl = 0;
  876.     while (uy != 0)
  877.     {
  878.       tmp[yl++] = extract(uy);
  879.       uy = down(uy);
  880.     }
  881.  
  882.     int rl = xl + yl;
  883.     int xrsame = x == r;
  884.     if (xrsame)
  885.       r = Iresize(r, rl);
  886.     else
  887.       r = Icalloc(r, rl);
  888.  
  889.     unsigned short* rs = r->s;
  890.     unsigned short* topr = &(rs[rl]);
  891.     unsigned short* currentr;
  892.     const unsigned short* bota;
  893.     const unsigned short* as;
  894.     const unsigned short* botb;
  895.     const unsigned short* topb;
  896.  
  897.     if (xrsame)
  898.     { 
  899.       currentr = &(rs[xl-1]);
  900.       bota = rs;
  901.       as = currentr;
  902.       botb = tmp;
  903.       topb = &(botb[yl]);
  904.     }
  905.     else if (xl <= yl)
  906.     {
  907.       currentr = &(rs[xl-1]);
  908.       bota = x->s;
  909.       as = &(bota[xl-1]);
  910.       botb = tmp;
  911.       topb = &(botb[yl]);
  912.     }
  913.     else
  914.     {
  915.       currentr = &(rs[yl-1]);
  916.       bota = tmp;
  917.       as = &(bota[yl-1]);
  918.       botb = x->s;
  919.       topb = &(botb[xl]);
  920.     }
  921.  
  922.     while (as >= bota)
  923.     {
  924.       unsigned long ai = (unsigned long)(*as--);
  925.       unsigned short* rs = currentr--;
  926.       *rs = 0;
  927.       if (ai != 0)
  928.       {
  929.         unsigned long sum = 0;
  930.         const unsigned short* bs = botb;
  931.         while (bs < topb)
  932.         {
  933.           sum += ai * (unsigned long)(*bs++) + (unsigned long)(*rs);
  934.           *rs++ = extract(sum);
  935.           sum = down(sum);
  936.         }
  937.         while (sum != 0 && rs < topr)
  938.         {
  939.           sum += (unsigned long)(*rs);
  940.           *rs++ = extract(sum);
  941.           sum = down(sum);
  942.         }
  943.       }
  944.     }
  945.     r->sgn = rsgn;
  946.   }
  947.   Icheck(r);
  948.   return r;
  949. }
  950.  
  951.  
  952. // main division routine
  953.  
  954. static void do_divide(unsigned short* rs,
  955.                       const unsigned short* ys, int yl,
  956.                       unsigned short* qs, int ql)
  957. {
  958.   const unsigned short* topy = &(ys[yl]);
  959.   unsigned short d1 = ys[yl - 1];
  960.   unsigned short d2 = ys[yl - 2];
  961.  
  962.   int l = ql - 1;
  963.   int i = l + yl;
  964.   
  965.   for (; l >= 0; --l, --i)
  966.   {
  967.     unsigned short qhat;       // guess q
  968.     if (d1 == rs[i])
  969.       qhat = I_MAXNUM;
  970.     else
  971.     {
  972.       unsigned long lr = up((unsigned long)rs[i]) | rs[i-1];
  973.       qhat = lr / d1;
  974.     }
  975.  
  976.     for(;;)     // adjust q, use docmp to avoid overflow problems
  977.     {
  978.       unsigned short ts[3];
  979.       unsigned long prod = (unsigned long)d2 * (unsigned long)qhat;
  980.       ts[0] = extract(prod);
  981.       prod = down(prod) + (unsigned long)d1 * (unsigned long)qhat;
  982.       ts[1] = extract(prod);
  983.       ts[2] = extract(down(prod));
  984.       if (docmp(ts, &(rs[i-2]), 3) > 0)
  985.         --qhat;
  986.       else
  987.         break;
  988.     };
  989.     
  990.     // multiply & subtract
  991.     
  992.     const unsigned short* yt = ys;
  993.     unsigned short* rt = &(rs[l]);
  994.     unsigned long prod = 0;
  995.     unsigned long hi = 1;
  996.     while (yt < topy)
  997.     {
  998.       prod = (unsigned long)qhat * (unsigned long)(*yt++) + down(prod);
  999.       hi += (unsigned long)(*rt) + I_MAXNUM - (unsigned long)(extract(prod));
  1000.       *rt++ = extract(hi);
  1001.       hi = down(hi);
  1002.     }
  1003.     hi += (unsigned long)(*rt) + I_MAXNUM - (unsigned long)(down(prod));
  1004.     *rt = extract(hi);
  1005.     hi = down(hi);
  1006.     
  1007.     // off-by-one, add back
  1008.     
  1009.     if (hi == 0)
  1010.     {
  1011.       --qhat;
  1012.       yt = ys;
  1013.       rt = &(rs[l]);
  1014.       hi = 0;
  1015.       while (yt < topy)
  1016.       {
  1017.         hi = (unsigned long)(*rt) + (unsigned long)(*yt++) + down(hi);
  1018.         *rt++ = extract(hi);
  1019.       }
  1020.       *rt = 0;
  1021.     }
  1022.     if (qs != 0)
  1023.       qs[l] = qhat;
  1024.   }
  1025. }
  1026.  
  1027. // divide by single digit, return remainder
  1028. // if q != 0, then keep the result in q, else just compute rem
  1029.  
  1030. static int unscale(const unsigned short* x, int xl, unsigned short y,
  1031.                    unsigned short* q)
  1032. {
  1033.   if (xl == 0 || y == 1)
  1034.     return 0;
  1035.   else if (q != 0)
  1036.   {
  1037.     unsigned short* botq = q;
  1038.     unsigned short* qs = &(botq[xl - 1]);
  1039.     const unsigned short* xs = &(x[xl - 1]);
  1040.     unsigned long rem = 0;
  1041.     while (qs >= botq)
  1042.     {
  1043.       rem = up(rem) | *xs--;
  1044.       unsigned long u = rem / y;
  1045.       *qs-- = extract(u);
  1046.       rem -= u * y;
  1047.     }
  1048.     int r = extract(rem);
  1049.     return r;
  1050.   }
  1051.   else                          // same loop, a bit faster if just need rem
  1052.   {
  1053.     const unsigned short* botx = x;
  1054.     const unsigned short* xs = &(botx[xl - 1]);
  1055.     unsigned long rem = 0;
  1056.     while (xs >= botx)
  1057.     {
  1058.       rem = up(rem) | *xs--;
  1059.       unsigned long u = rem / y;
  1060.       rem -= u * y;
  1061.     }
  1062.     int r = extract(rem);
  1063.     return r;
  1064.   }
  1065. }
  1066.  
  1067.  
  1068. IntRep* div(const IntRep* x, const IntRep* y, IntRep* q)
  1069. {
  1070.   nonnil(x);
  1071.   nonnil(y);
  1072.   int xl = x->len;
  1073.   int yl = y->len;
  1074.   if (yl == 0) (*lib_error_handler)("Integer", "attempted division by zero");
  1075.  
  1076.   int comp = ucompare(x, y);
  1077.   int xsgn = x->sgn;
  1078.   int ysgn = y->sgn;
  1079.  
  1080.   int samesign = xsgn == ysgn;
  1081.  
  1082.   if (comp < 0)
  1083.     q = Icopy_zero(q);
  1084.   else if (comp == 0)
  1085.     q = Icopy_one(q, samesign);
  1086.   else if (yl == 1)
  1087.   {
  1088.     q = Icopy(q, x);
  1089.     unscale(q->s, q->len, y->s[0], q->s);
  1090.   }
  1091.   else
  1092.   {
  1093.     IntRep* yy = 0;
  1094.     IntRep* r  = 0;
  1095.     unsigned short prescale = (I_RADIX / (1 + y->s[yl - 1]));
  1096.     if (prescale != 1 || y == q)
  1097.     {
  1098.       yy = multiply(y, ((long)prescale & I_MAXNUM), yy);
  1099.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1100.     }
  1101.     else
  1102.     {
  1103.       yy = (IntRep*)y;
  1104.       r = Icalloc(r, xl + 1);
  1105.       scpy(x->s, r->s, xl);
  1106.     }
  1107.  
  1108.     int ql = xl - yl + 1;
  1109.       
  1110.     q = Icalloc(q, ql);
  1111.     do_divide(r->s, yy->s, yl, q->s, ql);
  1112.  
  1113.     if (yy != y && !STATIC_IntRep(yy)) delete yy;
  1114.     if (!STATIC_IntRep(r)) delete r;
  1115.   }
  1116.   q->sgn = samesign;
  1117.   Icheck(q);
  1118.   return q;
  1119. }
  1120.  
  1121. IntRep* div(const IntRep* x, long y, IntRep* q)
  1122. {
  1123.   nonnil(x);
  1124.   int xl = x->len;
  1125.   if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");
  1126.  
  1127.   unsigned short ys[SHORT_PER_LONG];
  1128.   unsigned long u;
  1129.   int ysgn = y >= 0;
  1130.   if (ysgn)
  1131.     u = y;
  1132.   else
  1133.     u = -y;
  1134.   int yl = 0;
  1135.   while (u != 0)
  1136.   {
  1137.     ys[yl++] = extract(u);
  1138.     u = down(u);
  1139.   }
  1140.  
  1141.   int comp = xl - yl;
  1142.   if (comp == 0) comp = docmp(x->s, ys, xl);
  1143.  
  1144.   int xsgn = x->sgn;
  1145.   int samesign = xsgn == ysgn;
  1146.  
  1147.   if (comp < 0)
  1148.     q = Icopy_zero(q);
  1149.   else if (comp == 0)
  1150.   {
  1151.     q = Icopy_one(q, samesign);
  1152.   }
  1153.   else if (yl == 1)
  1154.   {
  1155.     q = Icopy(q, x);
  1156.     unscale(q->s, q->len, ys[0], q->s);
  1157.   }
  1158.   else
  1159.   {
  1160.     IntRep* r  = 0;
  1161.     unsigned short prescale = (I_RADIX / (1 + ys[yl - 1]));
  1162.     if (prescale != 1)
  1163.     {
  1164.       unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];
  1165.       ys[0] = extract(prod);
  1166.       prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];
  1167.       ys[1] = extract(prod);
  1168.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1169.     }
  1170.     else
  1171.     {
  1172.       r = Icalloc(r, xl + 1);
  1173.       scpy(x->s, r->s, xl);
  1174.     }
  1175.  
  1176.     int ql = xl - yl + 1;
  1177.       
  1178.     q = Icalloc(q, ql);
  1179.     do_divide(r->s, ys, yl, q->s, ql);
  1180.  
  1181.     if (!STATIC_IntRep(r)) delete r;
  1182.   }
  1183.   q->sgn = samesign;
  1184.   Icheck(q);
  1185.   return q;
  1186. }
  1187.  
  1188.  
  1189. void divide(const Integer& Ix, long y, Integer& Iq, long& rem)
  1190. {
  1191.   const IntRep* x = Ix.rep;
  1192.   nonnil(x);
  1193.   IntRep* q = Iq.rep;
  1194.   int xl = x->len;
  1195.   if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");
  1196.  
  1197.   unsigned short ys[SHORT_PER_LONG];
  1198.   unsigned long u;
  1199.   int ysgn = y >= 0;
  1200.   if (ysgn)
  1201.     u = y;
  1202.   else
  1203.     u = -y;
  1204.   int yl = 0;
  1205.   while (u != 0)
  1206.   {
  1207.     ys[yl++] = extract(u);
  1208.     u = down(u);
  1209.   }
  1210.  
  1211.   int comp = xl - yl;
  1212.   if (comp == 0) comp = docmp(x->s, ys, xl);
  1213.  
  1214.   int xsgn = x->sgn;
  1215.   int samesign = xsgn == ysgn;
  1216.  
  1217.   if (comp < 0)
  1218.   {
  1219.     rem = Itolong(x);
  1220.     q = Icopy_zero(q);
  1221.   }
  1222.   else if (comp == 0)
  1223.   {
  1224.     q = Icopy_one(q, samesign);
  1225.     rem = 0;
  1226.   }
  1227.   else if (yl == 1)
  1228.   {
  1229.     q = Icopy(q, x);
  1230.     rem = unscale(q->s, q->len, ys[0], q->s);
  1231.   }
  1232.   else
  1233.   {
  1234.     IntRep* r  = 0;
  1235.     unsigned short prescale = (I_RADIX / (1 + ys[yl - 1]));
  1236.     if (prescale != 1)
  1237.     {
  1238.       unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];
  1239.       ys[0] = extract(prod);
  1240.       prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];
  1241.       ys[1] = extract(prod);
  1242.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1243.     }
  1244.     else
  1245.     {
  1246.       r = Icalloc(r, xl + 1);
  1247.       scpy(x->s, r->s, xl);
  1248.     }
  1249.  
  1250.     int ql = xl - yl + 1;
  1251.       
  1252.     q = Icalloc(q, ql);
  1253.     
  1254.     do_divide(r->s, ys, yl, q->s, ql);
  1255.  
  1256.     if (prescale != 1)
  1257.     {
  1258.       Icheck(r);
  1259.       unscale(r->s, r->len, prescale, r->s);
  1260.     }
  1261.     Icheck(r);
  1262.     rem = Itolong(r);
  1263.     if (!STATIC_IntRep(r)) delete r;
  1264.   }
  1265.   rem = abs(rem);
  1266.   if (xsgn == I_NEGATIVE) rem = -rem;
  1267.   q->sgn = samesign;
  1268.   Icheck(q);
  1269.   Iq.rep = q;
  1270. }
  1271.  
  1272.  
  1273. void divide(const Integer& Ix, const Integer& Iy, Integer& Iq, Integer& Ir)
  1274. {
  1275.   const IntRep* x = Ix.rep;
  1276.   nonnil(x);
  1277.   const IntRep* y = Iy.rep;
  1278.   nonnil(y);
  1279.   IntRep* q = Iq.rep;
  1280.   IntRep* r = Ir.rep;
  1281.  
  1282.   int xl = x->len;
  1283.   int yl = y->len;
  1284.   if (yl == 0)
  1285.     (*lib_error_handler)("Integer", "attempted division by zero");
  1286.  
  1287.   int comp = ucompare(x, y);
  1288.   int xsgn = x->sgn;
  1289.   int ysgn = y->sgn;
  1290.  
  1291.   int samesign = xsgn == ysgn;
  1292.  
  1293.   if (comp < 0)
  1294.   {
  1295.     q = Icopy_zero(q);
  1296.     r = Icopy(r, x);
  1297.   }
  1298.   else if (comp == 0)
  1299.   {
  1300.     q = Icopy_one(q, samesign);
  1301.     r = Icopy_zero(r);
  1302.   }
  1303.   else if (yl == 1)
  1304.   {
  1305.     q = Icopy(q, x);
  1306.     int rem =  unscale(q->s, q->len, y->s[0], q->s);
  1307.     r = Icopy_long(r, rem);
  1308.     if (rem != 0)
  1309.       r->sgn = xsgn;
  1310.   }
  1311.   else
  1312.   {
  1313.     IntRep* yy = 0;
  1314.     unsigned short prescale = (I_RADIX / (1 + y->s[yl - 1]));
  1315.     if (prescale != 1 || y == q || y == r)
  1316.     {
  1317.       yy = multiply(y, ((long)prescale & I_MAXNUM), yy);
  1318.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1319.     }
  1320.     else
  1321.     {
  1322.       yy = (IntRep*)y;
  1323.       r = Icalloc(r, xl + 1);
  1324.       scpy(x->s, r->s, xl);
  1325.     }
  1326.  
  1327.     int ql = xl - yl + 1;
  1328.       
  1329.     q = Icalloc(q, ql);
  1330.     do_divide(r->s, yy->s, yl, q->s, ql);
  1331.  
  1332.     if (yy != y && !STATIC_IntRep(yy)) delete yy;
  1333.     if (prescale != 1)
  1334.     {
  1335.       Icheck(r);
  1336.       unscale(r->s, r->len, prescale, r->s);
  1337.     }
  1338.   }
  1339.   q->sgn = samesign;
  1340.   Icheck(q);
  1341.   Iq.rep = q;
  1342.   Icheck(r);
  1343.   Ir.rep = r;
  1344. }
  1345.  
  1346. IntRep* mod(const IntRep* x, const IntRep* y, IntRep* r)
  1347. {
  1348.   nonnil(x);
  1349.   nonnil(y);
  1350.   int xl = x->len;
  1351.   int yl = y->len;
  1352.   if (yl == 0) (*lib_error_handler)("Integer", "attempted division by zero");
  1353.  
  1354.   int comp = ucompare(x, y);
  1355.   int xsgn = x->sgn;
  1356.  
  1357.   if (comp < 0)
  1358.     r = Icopy(r, x);
  1359.   else if (comp == 0)
  1360.     r = Icopy_zero(r);
  1361.   else if (yl == 1)
  1362.   {
  1363.     int rem = unscale(x->s, xl, y->s[0], 0);
  1364.     r = Icopy_long(r, rem);
  1365.     if (rem != 0)
  1366.       r->sgn = xsgn;
  1367.   }
  1368.   else
  1369.   {
  1370.     IntRep* yy = 0;
  1371.     unsigned short prescale = (I_RADIX / (1 + y->s[yl - 1]));
  1372.     if (prescale != 1 || y == r)
  1373.     {
  1374.       yy = multiply(y, ((long)prescale & I_MAXNUM), yy);
  1375.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1376.     }
  1377.     else
  1378.     {
  1379.       yy = (IntRep*)y;
  1380.       r = Icalloc(r, xl + 1);
  1381.       scpy(x->s, r->s, xl);
  1382.     }
  1383.       
  1384.     do_divide(r->s, yy->s, yl, 0, xl - yl + 1);
  1385.  
  1386.     if (yy != y && !STATIC_IntRep(yy)) delete yy;
  1387.  
  1388.     if (prescale != 1)
  1389.     {
  1390.       Icheck(r);
  1391.       unscale(r->s, r->len, prescale, r->s);
  1392.     }
  1393.   }
  1394.   Icheck(r);
  1395.   return r;
  1396. }
  1397.  
  1398. IntRep* mod(const IntRep* x, long y, IntRep* r)
  1399. {
  1400.   nonnil(x);
  1401.   int xl = x->len;
  1402.   if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");
  1403.  
  1404.   unsigned short ys[SHORT_PER_LONG];
  1405.   unsigned long u;
  1406.   int ysgn = y >= 0;
  1407.   if (ysgn)
  1408.     u = y;
  1409.   else
  1410.     u = -y;
  1411.   int yl = 0;
  1412.   while (u != 0)
  1413.   {
  1414.     ys[yl++] = extract(u);
  1415.     u = down(u);
  1416.   }
  1417.  
  1418.   int comp = xl - yl;
  1419.   if (comp == 0) comp = docmp(x->s, ys, xl);
  1420.  
  1421.   int xsgn = x->sgn;
  1422.  
  1423.   if (comp < 0)
  1424.     r = Icopy(r, x);
  1425.   else if (comp == 0)
  1426.     r = Icopy_zero(r);
  1427.   else if (yl == 1)
  1428.   {
  1429.     int rem = unscale(x->s, xl, ys[0], 0);
  1430.     r = Icopy_long(r, rem);
  1431.     if (rem != 0)
  1432.       r->sgn = xsgn;
  1433.   }
  1434.   else
  1435.   {
  1436.     unsigned short prescale = (I_RADIX / (1 + ys[yl - 1]));
  1437.     if (prescale != 1)
  1438.     {
  1439.       unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];
  1440.       ys[0] = extract(prod);
  1441.       prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];
  1442.       ys[1] = extract(prod);
  1443.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1444.     }
  1445.     else
  1446.     {
  1447.       r = Icalloc(r, xl + 1);
  1448.       scpy(x->s, r->s, xl);
  1449.     }
  1450.       
  1451.     do_divide(r->s, ys, yl, 0, xl - yl + 1);
  1452.  
  1453.     if (prescale != 1)
  1454.     {
  1455.       Icheck(r);
  1456.       unscale(r->s, r->len, prescale, r->s);
  1457.     }
  1458.   }
  1459.   Icheck(r);
  1460.   return r;
  1461. }
  1462.  
  1463. IntRep* lshift(const IntRep* x, long y, IntRep* r)
  1464. {
  1465.   nonnil(x);
  1466.   int xl = x->len;
  1467.   if (xl == 0 || y == 0)
  1468.   {
  1469.     r = Icopy(r, x);
  1470.     return r;
  1471.   }
  1472.  
  1473.   int xrsame = x == r;
  1474.   int rsgn = x->sgn;
  1475.  
  1476.   long ay = (y < 0)? -y : y;
  1477.   int bw = ay / I_SHIFT;
  1478.   int sw = ay % I_SHIFT;
  1479.  
  1480.   if (y > 0)
  1481.   {
  1482.     int rl = bw + xl + 1;
  1483.     if (xrsame)
  1484.       r = Iresize(r, rl);
  1485.     else
  1486.       r = Icalloc(r, rl);
  1487.  
  1488.     unsigned short* botr = r->s;
  1489.     unsigned short* rs = &(botr[rl - 1]);
  1490.     const unsigned short* botx = (xrsame)? botr : x->s;
  1491.     const unsigned short* xs = &(botx[xl - 1]);
  1492.     unsigned long a = 0;
  1493.     while (xs >= botx)
  1494.     {
  1495.       a = up(a) | ((unsigned long)(*xs--) << sw);
  1496.       *rs-- = extract(down(a));
  1497.     }
  1498.     *rs-- = extract(a);
  1499.     while (rs >= botr)
  1500.       *rs-- = 0;
  1501.   }
  1502.   else
  1503.   {
  1504.     int rl = xl - bw;
  1505.     if (rl < 0)
  1506.       r = Icopy_zero(r);
  1507.     else
  1508.     {
  1509.       if (xrsame)
  1510.         r = Iresize(r, rl);
  1511.       else
  1512.         r = Icalloc(r, rl);
  1513.       int rw = I_SHIFT - sw;
  1514.       unsigned short* rs = r->s;
  1515.       unsigned short* topr = &(rs[rl]);
  1516.       const unsigned short* botx = (xrsame)? rs : x->s;
  1517.       const unsigned short* xs =  &(botx[bw]);
  1518.       const unsigned short* topx = &(botx[xl]);
  1519.       unsigned long a = (unsigned long)(*xs++) >> sw;
  1520.       while (xs < topx)
  1521.       {
  1522.         a |= (unsigned long)(*xs++) << rw;
  1523.         *rs++ = extract(a);
  1524.         a = down(a);
  1525.       }
  1526.       *rs++ = extract(a);
  1527.       if (xrsame) topr = (unsigned short*)topx;
  1528.       while (rs < topr)
  1529.         *rs++ = 0;
  1530.     }
  1531.   }
  1532.   r->sgn = rsgn;
  1533.   Icheck(r);
  1534.   return r;
  1535. }
  1536.  
  1537. IntRep* lshift(const IntRep* x, const IntRep* yy, int negatey, IntRep* r)
  1538. {
  1539.   long y = Itolong(yy);
  1540.   if (negatey)
  1541.     y = -y;
  1542.  
  1543.   return lshift(x, y, r);
  1544. }
  1545.  
  1546. IntRep* bitop(const IntRep* x, const IntRep* y, IntRep* r, char op)
  1547. {
  1548.   nonnil(x);
  1549.   nonnil(y);
  1550.   int xl = x->len;
  1551.   int yl = y->len;
  1552.   int xsgn = x->sgn;
  1553.   int xrsame = x == r;
  1554.   int yrsame = y == r;
  1555.   if (xrsame || yrsame)
  1556.     r = Iresize(r, calc_len(xl, yl, 0));
  1557.   else
  1558.     r = Icalloc(r, calc_len(xl, yl, 0));
  1559.   r->sgn = xsgn;
  1560.   unsigned short* rs = r->s;
  1561.   unsigned short* topr = &(rs[r->len]);
  1562.   const unsigned short* as;
  1563.   const unsigned short* bs;
  1564.   const unsigned short* topb;
  1565.   if (xl >= yl)
  1566.   {
  1567.     as = (xrsame)? rs : x->s;
  1568.     bs = (yrsame)? rs : y->s;
  1569.     topb = &(bs[yl]);
  1570.   }
  1571.   else
  1572.   {
  1573.     bs = (xrsame)? rs : x->s;
  1574.     topb = &(bs[xl]);
  1575.     as = (yrsame)? rs : y->s;
  1576.   }
  1577.  
  1578.   switch (op)
  1579.   {
  1580.   case '&':
  1581.     while (bs < topb) *rs++ = *as++ & *bs++;
  1582.     while (rs < topr) *rs++ = 0;
  1583.     break;
  1584.   case '|':
  1585.     while (bs < topb) *rs++ = *as++ | *bs++;
  1586.     while (rs < topr) *rs++ = *as++;
  1587.     break;
  1588.   case '^':
  1589.     while (bs < topb) *rs++ = *as++ ^ *bs++;
  1590.     while (rs < topr) *rs++ = *as++;
  1591.     break;
  1592.   }
  1593.   Icheck(r);
  1594.   return r;
  1595. }
  1596.  
  1597. IntRep* bitop(const IntRep* x, long y, IntRep* r, char op)
  1598. {
  1599.   nonnil(x);
  1600.   unsigned short tmp[SHORT_PER_LONG];
  1601.   unsigned long u;
  1602.   int newsgn;
  1603.   if (newsgn = (y >= 0))
  1604.     u = y;
  1605.   else
  1606.     u = -y;
  1607.   
  1608.   int l = 0;
  1609.   while (u != 0)
  1610.   {
  1611.     tmp[l++] = extract(u);
  1612.     u = down(u);
  1613.   }
  1614.  
  1615.   int xl = x->len;
  1616.   int yl = l;
  1617.   int xsgn = x->sgn;
  1618.   int xrsame = x == r;
  1619.   if (xrsame)
  1620.     r = Iresize(r, calc_len(xl, yl, 0));
  1621.   else
  1622.     r = Icalloc(r, calc_len(xl, yl, 0));
  1623.   r->sgn = xsgn;
  1624.   unsigned short* rs = r->s;
  1625.   unsigned short* topr = &(rs[r->len]);
  1626.   const unsigned short* as;
  1627.   const unsigned short* bs;
  1628.   const unsigned short* topb;
  1629.   if (xl >= yl)
  1630.   {
  1631.     as = (xrsame)? rs : x->s;
  1632.     bs = tmp;
  1633.     topb = &(bs[yl]);
  1634.   }
  1635.   else
  1636.   {
  1637.     bs = (xrsame)? rs : x->s;
  1638.     topb = &(bs[xl]);
  1639.     as = tmp;
  1640.   }
  1641.  
  1642.   switch (op)
  1643.   {
  1644.   case '&':
  1645.     while (bs < topb) *rs++ = *as++ & *bs++;
  1646.     while (rs < topr) *rs++ = 0;
  1647.     break;
  1648.   case '|':
  1649.     while (bs < topb) *rs++ = *as++ | *bs++;
  1650.     while (rs < topr) *rs++ = *as++;
  1651.     break;
  1652.   case '^':
  1653.     while (bs < topb) *rs++ = *as++ ^ *bs++;
  1654.     while (rs < topr) *rs++ = *as++;
  1655.     break;
  1656.   }
  1657.   Icheck(r);
  1658.   return r;
  1659. }
  1660.  
  1661.  
  1662.  
  1663. IntRep*  compl(const IntRep* src, IntRep* r)
  1664. {
  1665.   nonnil(src);
  1666.   r = Icopy(r, src);
  1667.   unsigned short* s = r->s;
  1668.   unsigned short* top = &(s[r->len - 1]);
  1669.   while (s < top)
  1670.   {
  1671.     unsigned short cmp = ~(*s);
  1672.     *s++ = cmp;
  1673.   }
  1674.   unsigned short a = *s;
  1675.   unsigned short b = 0;
  1676.   while (a != 0)
  1677.   {
  1678.     b <<= 1;
  1679.     if (!(a & 1)) b |= 1;
  1680.     a >>= 1;
  1681.   }
  1682.   *s = b;
  1683.   Icheck(r);
  1684.   return r;
  1685. }
  1686.  
  1687. void (setbit)(Integer& x, long b)
  1688. {
  1689.   if (b >= 0)
  1690.   {
  1691.     int bw = (unsigned long)b / I_SHIFT;
  1692.     int sw = (unsigned long)b % I_SHIFT;
  1693.     int xl = x.rep ? x.rep->len : 0;
  1694.     if (xl <= bw)
  1695.       x.rep = Iresize(x.rep, calc_len(xl, bw+1, 0));
  1696.     x.rep->s[bw] |= (1 << sw);
  1697.     Icheck(x.rep);
  1698.   }
  1699. }
  1700.  
  1701. void clearbit(Integer& x, long b)
  1702. {
  1703.   if (b >= 0)
  1704.     {
  1705.       if (x.rep == 0)
  1706.     x.rep = &_ZeroRep;
  1707.       else
  1708.     {
  1709.       int bw = (unsigned long)b / I_SHIFT;
  1710.       int sw = (unsigned long)b % I_SHIFT;
  1711.       if (x.rep->len > bw)
  1712.         x.rep->s[bw] &= ~(1 << sw);
  1713.     }
  1714.     Icheck(x.rep);
  1715.   }
  1716. }
  1717.  
  1718. int testbit(const Integer& x, long b)
  1719. {
  1720.   if (x.rep != 0 && b >= 0)
  1721.   {
  1722.     int bw = (unsigned long)b / I_SHIFT;
  1723.     int sw = (unsigned long)b % I_SHIFT;
  1724.     return (bw < x.rep->len && (x.rep->s[bw] & (1 << sw)) != 0);
  1725.   }
  1726.   else
  1727.     return 0;
  1728. }
  1729.  
  1730. // A  version of knuth's algorithm B / ex. 4.5.3.34
  1731. // A better version that doesn't bother shifting all of `t' forthcoming
  1732.  
  1733. IntRep* gcd(const IntRep* x, const IntRep* y)
  1734. {
  1735.   nonnil(x);
  1736.   nonnil(y);
  1737.   int ul = x->len;
  1738.   int vl = y->len;
  1739.   
  1740.   if (vl == 0)
  1741.     return Ialloc(0, x->s, ul, I_POSITIVE, ul);
  1742.   else if (ul == 0)
  1743.     return Ialloc(0, y->s, vl, I_POSITIVE, vl);
  1744.  
  1745.   IntRep* u = Ialloc(0, x->s, ul, I_POSITIVE, ul);
  1746.   IntRep* v = Ialloc(0, y->s, vl, I_POSITIVE, vl);
  1747.  
  1748. // find shift so that both not even
  1749.  
  1750.   long k = 0;
  1751.   int l = (ul <= vl)? ul : vl;
  1752.   int cont = 1;
  1753.   for (int i = 0;  i < l && cont; ++i)
  1754.   {
  1755.     unsigned long a =  (i < ul)? u->s[i] : 0;
  1756.     unsigned long b =  (i < vl)? v->s[i] : 0;
  1757.     for (int j = 0; j < I_SHIFT; ++j)
  1758.     {
  1759.       if ((a | b) & 1)
  1760.       {
  1761.         cont = 0;
  1762.         break;
  1763.       }
  1764.       else
  1765.       {
  1766.         ++k;
  1767.         a >>= 1;
  1768.         b >>= 1;
  1769.       }
  1770.     }
  1771.   }
  1772.  
  1773.   if (k != 0)
  1774.   {
  1775.     u = lshift(u, -k, u);
  1776.     v = lshift(v, -k, v);
  1777.   }
  1778.  
  1779.   IntRep* t;
  1780.   if (u->s[0] & 01)
  1781.     t = Ialloc(0, v->s, v->len, !v->sgn, v->len);
  1782.   else
  1783.     t = Ialloc(0, u->s, u->len, u->sgn, u->len);
  1784.  
  1785.   while (t->len != 0)
  1786.   {
  1787.     long s = 0;                 // shift t until odd
  1788.     cont = 1;
  1789.     int tl = t->len;
  1790.     for (int i = 0; i < tl && cont; ++i)
  1791.     {
  1792.       unsigned long a = t->s[i];
  1793.       for (int j = 0; j < I_SHIFT; ++j)
  1794.       {
  1795.         if (a & 1)
  1796.         {
  1797.           cont = 0;
  1798.           break;
  1799.         }
  1800.         else
  1801.         {
  1802.           ++s;
  1803.           a >>= 1;
  1804.         }
  1805.       }
  1806.     }
  1807.  
  1808.     if (s != 0) t = lshift(t, -s, t);
  1809.  
  1810.     if (t->sgn == I_POSITIVE)
  1811.     {
  1812.       u = Icopy(u, t);
  1813.       t = add(t, 0, v, 1, t);
  1814.     }
  1815.     else
  1816.     {
  1817.       v = Ialloc(v, t->s, t->len, !t->sgn, t->len);
  1818.       t = add(t, 0, u, 0, t);
  1819.     }
  1820.   }
  1821.   if (!STATIC_IntRep(t)) delete t;
  1822.   if (!STATIC_IntRep(v)) delete v;
  1823.   if (k != 0) u = lshift(u, k, u);
  1824.   return u;
  1825. }
  1826.  
  1827.  
  1828.  
  1829. long lg(const IntRep* x)
  1830. {
  1831.   nonnil(x);
  1832.   int xl = x->len;
  1833.   if (xl == 0)
  1834.     return 0;
  1835.  
  1836.   long l = (xl - 1) * I_SHIFT - 1;
  1837.   unsigned short a = x->s[xl-1];
  1838.  
  1839.   while (a != 0)
  1840.   {
  1841.     a = a >> 1;
  1842.     ++l;
  1843.   }
  1844.   return l;
  1845. }
  1846.   
  1847. IntRep* power(const IntRep* x, long y, IntRep* r)
  1848. {
  1849.   nonnil(x);
  1850.   int sgn;
  1851.   if (x->sgn == I_POSITIVE || (!(y & 1)))
  1852.     sgn = I_POSITIVE;
  1853.   else
  1854.     sgn = I_NEGATIVE;
  1855.  
  1856.   int xl = x->len;
  1857.  
  1858.   if (y == 0 || (xl == 1 && x->s[0] == 1))
  1859.     r = Icopy_one(r, sgn);
  1860.   else if (xl == 0 || y < 0)
  1861.     r = Icopy_zero(r);
  1862.   else if (y == 1 || y == -1)
  1863.     r = Icopy(r, x);
  1864.   else
  1865.   {
  1866.     int maxsize = ((lg(x) + 1) * y) / I_SHIFT + 2;     // pre-allocate space
  1867.     IntRep* b = Ialloc(0, x->s, xl, I_POSITIVE, maxsize);
  1868.     b->len = xl;
  1869.     r = Icalloc(r, maxsize);
  1870.     r = Icopy_one(r, I_POSITIVE);
  1871.     for(;;)
  1872.     {
  1873.       if (y & 1)
  1874.         r = multiply(r, b, r);
  1875.       if ((y >>= 1) == 0)
  1876.         break;
  1877.       else
  1878.         b = multiply(b, b, b);
  1879.     }
  1880.     if (!STATIC_IntRep(b)) delete b;
  1881.   }
  1882.   r->sgn = sgn;
  1883.   Icheck(r);
  1884.   return r;
  1885. }
  1886.  
  1887. IntRep* abs(const IntRep* src, IntRep* dest)
  1888. {
  1889.   nonnil(src);
  1890.   if (src != dest)
  1891.     dest = Icopy(dest, src);
  1892.   dest->sgn = I_POSITIVE;
  1893.   return dest;
  1894. }
  1895.  
  1896. IntRep* negate(const IntRep* src, IntRep* dest)
  1897. {
  1898.   nonnil(src);
  1899.   if (src != dest)
  1900.     dest = Icopy(dest, src);
  1901.   if (dest->len != 0) 
  1902.     dest->sgn = !dest->sgn;
  1903.   return dest;
  1904. }
  1905.  
  1906. #if defined(__GNUG__) && !defined(_G_NO_NRV)
  1907.  
  1908. Integer sqrt(const Integer& x) return r(x)
  1909. {
  1910.   int s = sign(x);
  1911.   if (s < 0) x.error("Attempted square root of negative Integer");
  1912.   if (s != 0)
  1913.   {
  1914.     r >>= (lg(x) / 2); // get close
  1915.     Integer q;
  1916.     div(x, r, q);
  1917.     while (q < r)
  1918.     {
  1919.       r += q;
  1920.       r >>= 1;
  1921.       div(x, r, q);
  1922.     }
  1923.   }
  1924.   return;
  1925. }
  1926.  
  1927. Integer lcm(const Integer& x, const Integer& y) return r
  1928. {
  1929.   if (!x.initialized() || !y.initialized())
  1930.     x.error("operation on uninitialized Integer");
  1931.   Integer g;
  1932.   if (sign(x) == 0 || sign(y) == 0)
  1933.     g = 1;
  1934.   else 
  1935.     g = gcd(x, y);
  1936.   div(x, g, r);
  1937.   mul(r, y, r);
  1938. }
  1939.  
  1940. #else 
  1941. Integer sqrt(const Integer& x) 
  1942. {
  1943.   Integer r(x);
  1944.   int s = sign(x);
  1945.   if (s < 0) x.error("Attempted square root of negative Integer");
  1946.   if (s != 0)
  1947.   {
  1948.     r >>= (lg(x) / 2); // get close
  1949.     Integer q;
  1950.     div(x, r, q);
  1951.     while (q < r)
  1952.     {
  1953.       r += q;
  1954.       r >>= 1;
  1955.       div(x, r, q);
  1956.     }
  1957.   }
  1958.   return r;
  1959. }
  1960.  
  1961. Integer lcm(const Integer& x, const Integer& y) 
  1962. {
  1963.   Integer r;
  1964.   if (!x.initialized() || !y.initialized())
  1965.     x.error("operation on uninitialized Integer");
  1966.   Integer g;
  1967.   if (sign(x) == 0 || sign(y) == 0)
  1968.     g = 1;
  1969.   else 
  1970.     g = gcd(x, y);
  1971.   div(x, g, r);
  1972.   mul(r, y, r);
  1973.   return r;
  1974. }
  1975.  
  1976. #endif
  1977.  
  1978.  
  1979.  
  1980. IntRep* atoIntRep(const char* s, int base)
  1981. {
  1982.   int sl = strlen(s);
  1983.   IntRep* r = Icalloc(0, sl * (lg(base) + 1) / I_SHIFT + 1);
  1984.   if (s != 0)
  1985.   {
  1986.     char sgn;
  1987.     while (isspace(*s)) ++s;
  1988.     if (*s == '-')
  1989.     {
  1990.       sgn = I_NEGATIVE;
  1991.       s++;
  1992.     }
  1993.     else if (*s == '+')
  1994.     {
  1995.       sgn = I_POSITIVE;
  1996.       s++;
  1997.     }
  1998.     else
  1999.       sgn = I_POSITIVE;
  2000.     for (;;)
  2001.     {
  2002.       long digit;
  2003.       if (*s >= '0' && *s <= '9') digit = *s - '0';
  2004.       else if (*s >= 'a' && *s <= 'z') digit = *s - 'a' + 10;
  2005.       else if (*s >= 'A' && *s <= 'Z') digit = *s - 'A' + 10;
  2006.       else break;
  2007.       if (digit >= base) break;
  2008.       r = multiply(r, base, r);
  2009.       r = add(r, 0, digit, r);
  2010.       ++s;
  2011.     }
  2012.     r->sgn = sgn;
  2013.   }
  2014.   return r;
  2015. }
  2016.  
  2017.  
  2018.  
  2019. extern AllocRing _libgxx_fmtq;
  2020.  
  2021. char* Itoa(const IntRep* x, int base, int width)
  2022. {
  2023.   int fmtlen = (x->len + 1) * I_SHIFT / lg(base) + 4 + width;
  2024.   char* fmtbase = (char *) _libgxx_fmtq.alloc(fmtlen);
  2025.   char* f = cvtItoa(x, fmtbase, fmtlen, base, 0, width, 0, ' ', 'X', 0);
  2026.   return f;
  2027. }
  2028.  
  2029. ostream& operator << (ostream& s, const Integer& y)
  2030. {
  2031. #ifdef _OLD_STREAMS
  2032.   return s << Itoa(y.rep);
  2033. #else
  2034.   if (s.opfx())
  2035.     {
  2036.       int base = (s.flags() & ios::oct) ? 8 : (s.flags() & ios::hex) ? 16 : 10;
  2037.       int width = s.width();
  2038.       y.printon(s, base, width);
  2039.     }
  2040.   return s;
  2041. #endif
  2042. }
  2043.  
  2044. void Integer::printon(ostream& s, int base /* =10 */, int width /* =0 */) const
  2045. {
  2046.   int align_right = !(s.flags() & ios::left);
  2047.   int showpos = s.flags() & ios::showpos;
  2048.   int showbase = s.flags() & ios::showbase;
  2049.   char fillchar = s.fill();
  2050.   char Xcase = (s.flags() & ios::uppercase)? 'X' : 'x';
  2051.   const IntRep* x = rep;
  2052.   int fmtlen = (x->len + 1) * I_SHIFT / lg(base) + 4 + width;
  2053.   char* fmtbase = new char[fmtlen];
  2054.   char* f = cvtItoa(x, fmtbase, fmtlen, base, showbase, width, align_right,
  2055.             fillchar, Xcase, showpos);
  2056.   s.write(f, fmtlen);
  2057.   delete [] fmtbase;
  2058. }
  2059.  
  2060. char*  cvtItoa(const IntRep* x, char* fmt, int& fmtlen, int base, int showbase,
  2061.               int width, int align_right, char fillchar, char Xcase, 
  2062.               int showpos)
  2063. {
  2064.   char* e = fmt + fmtlen - 1;
  2065.   char* s = e;
  2066.   *--s = 0;
  2067.  
  2068.   if (x->len == 0)
  2069.     *--s = '0';
  2070.   else
  2071.   {
  2072.     IntRep* z = Icopy(0, x);
  2073.  
  2074.     // split division by base into two parts: 
  2075.     // first divide by biggest power of base that fits in an unsigned short,
  2076.     // then use straight signed div/mods from there. 
  2077.  
  2078.     // find power
  2079.     int bpower = 1;
  2080.     unsigned short b = base;
  2081.     unsigned short maxb = I_MAXNUM / base;
  2082.     while (b < maxb)
  2083.     {
  2084.       b *= base;
  2085.       ++bpower;
  2086.     }
  2087.     for(;;)
  2088.     {
  2089.       int rem = unscale(z->s, z->len, b, z->s);
  2090.       Icheck(z);
  2091.       if (z->len == 0)
  2092.       {
  2093.         while (rem != 0)
  2094.         {
  2095.           char ch = rem % base;
  2096.           rem /= base;
  2097.           if (ch >= 10)
  2098.             ch += 'a' - 10;
  2099.           else
  2100.             ch += '0';
  2101.           *--s = ch;
  2102.         }
  2103.     if (!STATIC_IntRep(z)) delete z;
  2104.         break;
  2105.       }
  2106.       else
  2107.       {
  2108.         for (int i = 0; i < bpower; ++i)
  2109.         {
  2110.           char ch = rem % base;
  2111.           rem /= base;
  2112.           if (ch >= 10)
  2113.             ch += 'a' - 10;
  2114.           else
  2115.             ch += '0';
  2116.           *--s = ch;
  2117.         }
  2118.       }
  2119.     }
  2120.   }
  2121.  
  2122.   if (base == 8 && showbase) 
  2123.     *--s = '0';
  2124.   else if (base == 16 && showbase) 
  2125.   { 
  2126.     *--s = Xcase; 
  2127.     *--s = '0'; 
  2128.   }
  2129.   if (x->sgn == I_NEGATIVE) *--s = '-';
  2130.   else if (showpos) *--s = '+';
  2131.   int w = e - s - 1;
  2132.   if (!align_right || w >= width)
  2133.   {
  2134.     while (w++ < width)
  2135.       *--s = fillchar;
  2136.     fmtlen = e - s - 1;
  2137.     return s;
  2138.   }
  2139.   else
  2140.   {
  2141.     char* p = fmt;
  2142.     for (char* t = s; *t != 0; ++t, ++p) *p = *t;
  2143.     while (w++ < width) *p++ = fillchar;
  2144.     *p = 0;
  2145.     fmtlen = p - fmt;
  2146.     return fmt;
  2147.   }
  2148. }
  2149.  
  2150. char* dec(const Integer& x, int width)
  2151. {
  2152.   return Itoa(x, 10, width);
  2153. }
  2154.  
  2155. char* oct(const Integer& x, int width)
  2156. {
  2157.   return Itoa(x, 8, width);
  2158. }
  2159.  
  2160. char* hex(const Integer& x, int width)
  2161. {
  2162.   return Itoa(x, 16, width);
  2163. }
  2164.  
  2165. istream& operator >> (istream& stream, Integer& val)
  2166. {
  2167.   if (!stream.ipfx0())
  2168.     return stream;
  2169.   int sign = ' ';
  2170.   register streambuf* sb = stream.rdbuf();
  2171.   int base = 10;
  2172.   int ndigits = 0;
  2173.   register int ch = sb->sbumpc();
  2174.   while (ch != EOF && isspace(ch))
  2175.     ch = sb->sbumpc();
  2176.   if (ch == '+' || ch == '-')
  2177.     {
  2178.       sign = ch;
  2179.       ch = sb->sbumpc();
  2180.       while (ch != EOF && isspace(ch))
  2181.     ch = sb->sbumpc();
  2182.     }
  2183.   if (ch == EOF) goto eof_fail;
  2184.   if (!(stream.flags() & ios::basefield))
  2185.     {
  2186.       if (ch == '0')
  2187.     {
  2188.       ch = sb->sbumpc();
  2189.       if (ch == EOF) { }
  2190.       else if (ch == 'x' || ch == 'X')
  2191.         {
  2192.           base = 16;
  2193.           ch = sb->sbumpc();
  2194.           if (ch == EOF) goto eof_fail;
  2195.         }
  2196.       else
  2197.         {
  2198.           sb->sputbackc(ch);
  2199.           base = 8;
  2200.           ch = '0';
  2201.         }
  2202.     }
  2203.     }
  2204.   else if ((stream.flags() & ios::basefield) == ios::hex)
  2205.     base = 16;
  2206.   else if ((stream.flags() & ios::basefield) == ios::oct)
  2207.     base = 8;
  2208.  
  2209.   val.rep = Icopy_zero(val.rep);
  2210.  
  2211.   for (;;)
  2212.     {
  2213.       if (ch == EOF)
  2214.     break;
  2215.       int digit;
  2216.       if (ch >= '0' && ch <= '9')
  2217.     digit = ch - '0';
  2218.       else if (ch >= 'A' && ch <= 'F')
  2219.     digit = ch - 'A' + 10;
  2220.       else if (ch >= 'a' && ch <= 'f')
  2221.     digit = ch - 'a' + 10;
  2222.       else
  2223.     digit = 999;
  2224.       if (digit >= base)
  2225.     {
  2226.       sb->sputbackc(ch);
  2227.       if (ndigits == 0)
  2228.         goto fail;
  2229.       else
  2230.         goto done;
  2231.     }
  2232.       ndigits++;
  2233.       switch (base)
  2234.     {
  2235.     case 8:
  2236.       val <<= 3;
  2237.       break;
  2238.     case 16:
  2239.       val <<= 4;
  2240.       break;
  2241.     default:
  2242.       val *= base;
  2243.       break;
  2244.     }
  2245.       val += digit;
  2246.       ch = sb->sbumpc();
  2247.     }
  2248.  fail:
  2249.   stream.set(ios::failbit);
  2250.  done:
  2251.   if (sign == '-')
  2252.     val.negate();
  2253.   return stream;
  2254.  eof_fail:
  2255.   stream.set(ios::failbit|ios::eofbit);
  2256.   return stream;
  2257. }
  2258.  
  2259. int Integer::OK() const
  2260. {
  2261.   if (rep != 0)
  2262.     {
  2263.       int l = rep->len;
  2264.       int s = rep->sgn;
  2265.       int v = l <= rep->sz || STATIC_IntRep(rep);    // length within bounds
  2266.       v &= s == 0 || s == 1;        // legal sign
  2267.       Icheck(rep);                  // and correctly adjusted
  2268.       v &= rep->len == l;
  2269.       v &= rep->sgn == s;
  2270.       if (v)
  2271.       return v;
  2272.     }
  2273.   error("invariant failure");
  2274.   return 0;
  2275. }
  2276.  
  2277. void Integer::error(const char* msg) const
  2278. {
  2279.   (*lib_error_handler)("Integer", msg);
  2280. }
  2281.  
  2282.